﻿#include "ssReadBytes.h"
#include "../dump/ssException.h"

namespace StarSeeker
{

ssReadBytes::ssReadBytes()
	:m_buffer(0),m_pos(0),m_size(0)
{
}

ssReadBytes::~ssReadBytes()
{
}

ssReadBytes::ssReadBytes(const char* buffer, ulint size)
	:m_buffer(buffer),m_pos(0),m_size(size)
{
}

void ssReadBytes::Set(const char* buffer, ulint size)
{
	m_buffer=buffer;
	m_size=size;
	m_pos=0;
}

bool ssReadBytes::ReadBuffer(void* p, ulint size)
{
	if ( size+m_pos>m_size )
	{
		SS_THROW("ReadBuffer Out Of Size!");
		return false;
	}
	memcpy(p, m_buffer+m_pos, size);
	m_pos += size;
	return true;
}

const char* ssReadBytes::ReadBuffer(ulint size)
{
	if ( size+m_pos>m_size )
	{
		SS_THROW("ReadBuffer Out Of Size!");
		return 0;
	}
	m_pos += size;
	return m_buffer+m_pos-size;
}

u32 ssReadBytes::ReadString(char* pBuf, u32 bufSize)
{
	u32 strLen = 0;
	if (ReadU32(strLen))
	{
		if (strLen==0)
		{
			pBuf[0] = 0;
			return 0;
		}
		else if (strLen<bufSize)
		{
			ReadBuffer(pBuf, strLen);
			pBuf[strLen] = 0;
			return strLen;
		}
	}
	return 0;
}

bool ssReadBytes::ReadString(std::string& str)
{
	u32 strLen = 0;
	if (ReadU32(strLen))
	{
		str.clear();
		if (strLen == 0)
		{
			return true;
		}
		else if (strLen < 2048)
		{
			str.assign(m_buffer + m_pos, strLen);
			Skip(strLen);
			return true;
		}
	}
	return false;
}

u32 ssReadBytes::ReadStruct(void* pbuf, u32 bufSize)
{
	u32 realSize = 0;
	if (ReadU32(realSize))
	{
		if (realSize==0)
		{
			return 0;
		}
		else if (realSize<=bufSize)
		{
			ReadBuffer(pbuf, realSize);
			return realSize;
		}
	}
	return 0;
}

bool ssReadBytes::Skip(ulint size) const
{
	if ( (size+m_pos)>m_size )
		return false;
	m_pos += size;
	return true;
}

ulint ssReadBytes::GetLine(char* pbuf, u32 bufSize)
{
	ulint begin = SS_INVAILD_UINT;
	ulint end = 0;
	ulint skip = 0;
	for (ulint i=m_pos; i<m_size; ++i)
	{
		if (i==m_size-1)
		{
			begin = m_pos;
			end = i;
			break;
		}
		else if (m_buffer[i]=='\r' || m_buffer[i]=='\n')
		{
			begin = m_pos;
			end = i;
			skip = 1;
			for (ulint j=i+1; j<m_size; ++j)
			{
				if (m_buffer[j]=='\r' || m_buffer[j]=='\n')
				{
					end = j;
					++skip;
				}
				else
				{
					break;
				}
			}
			break;
		}
	}
	if (begin != SS_INVAILD_UINT)
	{
		ulint ret = end-begin+1-skip;
		if (ret < bufSize)
		{
			memcpy(pbuf, m_buffer+begin, ret);
			pbuf[ret] = 0;
			m_pos = end+1;
			return ret;
		}
	}
	return 0;
}

}
